/**
* \file Vaisseau.h
* \brief Prototypes des methodes de la classe Vaisseau
* \author FEKI Mehdi && RIPOCHE Emilien
* \version 1.0
* \date 04/12/2011
*/

#pragma once

#include "Position.h"
#include "Plateau.h"

#include <iostream>


/** \def NBCHARGESMAXVM Le nombre de charges maximal 
 * qui peut etre present dans un vaisseau mere
 */
#define NBCHARGESMAXVM 3

/** \def NBCHARGESMAXBA Le nombre de charges maximal 
 * qui peut etre present dans un battlecruiser
 */
#define NBCHARGESMAXBA 2

/** \def NBCHARGESMAXCA Le nombre de charges maximal 
 * qui peut etre present dans une capsule de survie
 */
#define NBCHARGESMAXCA 1

/** \def NBREBONDSMAXVM Le nombre maximal de rebonds 
 * que peut effectuer le tir d'un vaisseau mere
 */
#define NBREBONDSMAXVM 5

/** \def NBREBONDSMAXBA Le nombre maximal de rebonds 
 * que peut effectuer le tir d'un battlecruiser
 */
#define NBREBONDSMAXBA 4

/** \def NBREBONDSMAXCA Le nombre maximal de rebonds 
 * que peut effectuer le tir d'une capsule de survie
 */
#define NBREBONDSMAXCA 3

 
/**
 * \class Classe Vaisseau
 * \brief Classe abstraite representant un vaisseau
 */
class __declspec( dllexport ) Vaisseau {

public:
	enum TypeVaisseau { VaisseauMere, Battlecruiser, Capsule };
protected:
	unsigned int _nbCharges;	/*!< Nombre de charges courant dans le vaisseau */
	bool _hasArtefact;			/*!< Booleen specifiant la presence d'un artefact dans le vaisseau */
	int _x;						/*!< Position du vaisseau sur l'axe des abscisses */
	int _y;						/*!< Position du vaisseau sur l'axe des ordonnees */

public:
	/* ----- CONSTRUCTEURS ----- */
	/**
		* \fn Vaisseau()
		* \brief Constructeur de la classe Vaisseau
		*/
	Vaisseau();

	/**
		* \fn Vaisseau(int posX, int posY)
		* \brief Constructeur de la classe Vaisseau
		* \param posX Position initiale du vaisseau sur l'axe des abscisses
		* \param posY Position initiale du vaisseau sur l'axe des ordonnees
		*/
	Vaisseau(int posX, int posY);


	/* ----- GETTERS ----- */	 
	/**
		* \fn unsigned int getNbCharges() const
		* \brief Getter pour l'attribut _nbCharges
		* \return L'attribut _nbCharges
		*/
	unsigned int getNbCharges() const { return _nbCharges; }

	/**
		* \fn bool hasArtefact() const
		* \brief Getter pour l'attribut _hasArtefact
		* \return L'attribut _hasArtefact
		*/
	bool hasArtefact() const { return _hasArtefact; }

	/**
		* \fn int getX() const
		* \brief Getter pour l'attribut _x
		* \return L'attribut _x
		*/
	int getX() const { return _x; }

	/**
		* \fn int getY() const
		* \brief Getter pour l'attribut _y
		* \return L'attribut _y
		*/	
	int getY() const { return _y; }

	
	/* ----- SETTERS ----- */
	/**
		* \fn void setHasArtefact(bool b)
		* \brief Setter pour l'attribut _hasArtefact
		* \param b Nouvelle valeur de l'attribut _hasArtefact
		*/
	void setHasArtefact(bool b) { _hasArtefact = b; }
	 
	/**
	* \fn void setX(int posX)
	* \brief Setter pour l'attribut _x
	* \param posX Nouvelle valeur de l'attribut _x
	*/
	void setX(int posX) { _x = posX; }

	/**
	* \fn void setY(int posY)
	* \brief Setter pour l'attribut _y
	* \param posY Nouvelle valeur de l'attribut _y
	*/
	void setY(int posY) { _y = posY; }

	/**
	* \fn Position* getPosition() const
	* \brief Recupere la position du vaisseau
	* \return La position du vaisseau
	*/
	Position* getPosition() const { return new Position(_x, _y); }

	/**
	* \fn Case::TypeCase getTypeCase() const
	* \brief Recupere le type de la case occupee par le vaisseau
	* \return Le type de la case ocupee par le vaisseau
	*/
	Case::TypeCase getTypeCase() const { return Plateau::getSingletonPlateau()->getTypeCase(_x, _y); }

	/**
	* \fn Case* getCase() const
	* \brief Recupere la case occupee par le vaisseau
	* \return La case ocupee par le vaisseau
	*/
	Case* getCase() const { return  Plateau::getSingletonPlateau()->getCase(_x, _y); }


	/* ----- METHODES ----- */
	/**
		* \fn void deplacementAbsolu(int x, int y)
		* \brief Modifie la position du vaisseau avec de nouvelles coordonnees
		* \param x Nouvelle position sur l'axe des abscisses
		* \param y Nouvelle position sur l'axe des ordonnees
		*/
	void deplacementAbsolu(int x, int y) { setX(x); setY(y); };
	 
	/**
		* \fn void deplacementRelatif(int dx, int dy)
		* \brief Modifie la position du vaisseau avec un deplacement relatif
		* a la position actuelle
		* \param dx Deplacement sur l'axe des abscisses
		* \param dy Deplacement sur l'axe des ordonnees
		*/
	void deplacementRelatif(int dx, int dy) { setX(_x + dx); setY(_y + dy); };

	/**
		* \fn void majProprietes(int x, int y)
		* \brief Met a jour les proprietes du vaisseau en fonction de sa case
		*/
	void majProprietes(int x, int y);

	/**
		* \fn virtual bool tirer() = 0
		* \brief Methode vituelle pure
		*/
	virtual bool tirer() = 0;

	/**
		* \fn virtual bool charger() = 0
		* \brief Methode vituelle pure
		*/
	virtual bool charger() = 0;

	/**
		* \fn virtual typeVaisseau type() const = 0
		* \brief Methode vituelle pure
		*/
	virtual TypeVaisseau type() const = 0;
};